﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using IUAP.DAL;
using IUAP.DAL.Articulo;

/// <summary>
/// Descripción breve de Article
/// </summary>
namespace IUAP.BLL.Articulo
{
    public class Articulo : BaseArticulo
    {
        public Articulo(int id_articulo, DateTime fecha_arti, string usua_arti,int id_categoria, string titu_arti, string resu_arti,
         string cont_arti, string ciud_arti, DateTime fech_publ_arti, DateTime fech_expi_arti, bool apro_arti,
         bool list_arti, bool actv_comn_arti, bool solo_miem_arti, int cont_visi_arti, int voto_arti, int rank_arti)
        {
            this.Id = id_articulo;
            this.Fecha = fecha_arti;
            this.Usuario = usua_arti;
            this.Id_categoria = id_categoria;
            this.Titu_arti = titu_arti;
            this.Resu_arti = resu_arti;
            this.Cont_arti = cont_arti;
            this.Ciud_arti = ciud_arti;
            this.Fech_publ_arti = fech_publ_arti;
            this.Fech_expi_arti = fech_expi_arti;
            this.Apro_arti = apro_arti;
            this.List_arti = list_arti;
            this.Actv_comn_arti = actv_comn_arti;
            this.Solo_miem_arti = solo_miem_arti;
            this.Cont_visi_arti = cont_visi_arti;
            this.Voto_arti = voto_arti;
            this.Rank_arti = rank_arti;
        }
        private int id_categoria = 0;

        public int Id_categoria
        {
            get { return id_categoria; }
            set { id_categoria = value; }
        }

        private string titu_cate = "";

        public string Titu_cate
        {
            get { return titu_cate; }
            private set { titu_cate = value; }
        }

        private Categoria categoria = null;
        public Categoria Categoria
        {
            get
            {
                if (categoria == null)
                    categoria = Categoria.GetCategoryByID(this.Id_categoria);
                return categoria;
            }
        }

        private string titu_arti = "";

        public string Titu_arti
        {
            get { return titu_arti; }
            set { titu_arti = value; }
        }

        private string resu_arti = "";

        public string Resu_arti
        {
            get { return resu_arti; }
            set { resu_arti = value; }
        }

        private string cont_arti = null;

        public string Cont_arti
        {
            get 
            {
                if (cont_arti == null)
                    cont_arti = SiteProvider.Articulos.GetArticuloCont(this.Id);
                return cont_arti; 
            }
            set { cont_arti = value; }
        }
        private string ciud_arti = "";

        public string Ciud_arti
        {
            get { return ciud_arti; }
            set { ciud_arti = value; }
        }

        private DateTime fech_publ_arti = DateTime.Now;

        public DateTime Fech_publ_arti
        {
            get { return fech_publ_arti; }
            set { fech_publ_arti = value; }
        }

        private DateTime fech_expi_arti = DateTime.MaxValue;

        public DateTime Fech_expi_arti
        {
            get { return fech_expi_arti; }
            set { fech_expi_arti = value; }
        }

        private bool apro_arti = true;

        public bool Apro_arti
        {
            get { return apro_arti; }
            set { apro_arti = value; }
        }

        private bool list_arti = true;

        public bool List_arti
        {
            get { return list_arti; }
            set { list_arti = value; }
        }

        private bool actv_comn_arti = true;

        public bool Actv_comn_arti
        {
            get { return actv_comn_arti; }
            set { actv_comn_arti = value; }
        }

        private bool solo_miem_arti = true;

        public bool Solo_miem_arti
        {
            get { return solo_miem_arti; }
            set { solo_miem_arti = value; }
        }

        private int cont_visi_arti = 0;

        public int Cont_visi_arti
        {
            get { return cont_visi_arti; }
            private set { cont_visi_arti = value; }
        }

        private int voto_arti = 0;

        public int Voto_arti
        {
            get { return voto_arti; }
            private set { voto_arti = value; }
        }

        private int rank_arti = 0;

        public int Rank_arti
        {
            get { return rank_arti; }
            set { rank_arti = value; }
        }
        /// <summary>
        /// Propiedad que sirve para evitar la división si es que la cantidad de votos es 0.
        /// </summary>
        public double RatingMedio
        {
            get
            {
                if (this.Voto_arti >= 1)
                    return ((double)this.Rank_arti / (double)this.Voto_arti);
                else
                    return 0.0;
            }
        }

        private List<Comentario> comentario = null;
        public List<Comentario> Comments
        {
            get
            {
                if (comentario == null)
                    comentario = Comentario.GetComments(this.Id, 0, BizObject.MAXROWS);
                return comentario;
            }
        }

        /// <summary>
        /// Propiedad que deuelve un valor true si el articulo esta publicado
        ///  y la fecha actual esta entre la Fecha de Publicacion y Fecha de Expiracion.
        /// </summary>
        public bool Publicado
        {
            get
            {
                return (this.Apro_arti && this.Fech_publ_arti <= DateTime.Now &&
                   this.Fech_expi_arti > DateTime.Now);
            }
        }
        public bool Delete()
        {
            bool success = Articulo.DeleteArticle(this.Id);
            if (success)
                this.Id = 0;
            return success;
        }
        public bool Update()
        {
            return Articulo.UpdateArticulo(this.Id, this.Id_categoria, this.Titu_arti, this.Resu_arti, this.Cont_arti, 
                this.Ciud_arti, this.Fech_publ_arti, this.Fech_expi_arti, this.Apro_arti, this.List_arti,
               this.Actv_comn_arti, this.Solo_miem_arti);
        }
        public bool Aprobar()
        {
            bool success = Articulo.AprobarArticulo(this.Id);
            if (success)
                this.Apro_arti = true;
            return success;
        }
        public bool IncrementCantidadVisitas()
        {
            return Articulo.IncrementCantidadVisitas(this.Id);
        }

        public bool Rate(int rank_articulo)
        {
            return Articulo.InsertVoto(this.Id, rank_articulo);
        }
        
        //------------------Metodos Static--------------------------
        public static List<Articulo> GetArticles()
        {
            return GetArticles(0, BizObject.MAXROWS);
        }
        public static List<Articulo> GetArticles(int startRowIndex, int maximumRows)
        {
            List<Articulo> articles = null;
            string key = "Articles_Articles_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articles = (List<Articulo>)BizObject.Cache[key];
            }
            else
            {
                List<ArticuloDetalles> recordset = SiteProvider.Articulos.GetArticulo(
                   GetPageIndex(startRowIndex, maximumRows), maximumRows);
                articles = GetArticuloListDeArticuloDetallesList(recordset);
                BaseArticulo.CacheData(key, articles);
            }
            return articles;
        }
        public static List<Articulo> GetArticles(int id_categoria)
        {
            return GetArticles(id_categoria, 0, BizObject.MAXROWS);
        }
        public static List<Articulo> GetArticles(int categoryID, int startRowIndex, int maximumRows)
        {
            if (categoryID <= 0)
                return GetArticles(startRowIndex, maximumRows);

            List<Articulo> articles = null;
            string key = "Articles_Articles_" + categoryID.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articles = (List<Articulo>)BizObject.Cache[key];
            }
            else
            {
                List<ArticuloDetalles> recordset = SiteProvider.Articulos.GetArticulobyCategoria(categoryID,
                   GetPageIndex(startRowIndex, maximumRows), maximumRows);
                articles = GetArticuloListDeArticuloDetallesList(recordset);
                BaseArticulo.CacheData(key, articles);
            }
            return articles;
        }
        public static int GetArticleCount()
        {
            int articleCount = 0;
            string key = "Articles_ArticleCount";

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articleCount = (int)BizObject.Cache[key];
            }
            else
            {
                articleCount = SiteProvider.Articulos.GetArticleCount();
                BaseArticulo.CacheData(key, articleCount);
            }
            return articleCount;
        }
        public static int GetArticleCount(int id_categoria)
        {
            if (id_categoria <= 0)
                return GetArticleCount();

            int articleCount = 0;
            string key = "Articles_ArticleCount_" + id_categoria.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articleCount = (int)BizObject.Cache[key];
            }
            else
            {
                articleCount = SiteProvider.Articulos.GetContarArticulosbyCategoria(id_categoria);
                BaseArticulo.CacheData(key, articleCount);
            }
            return articleCount;
        }
        public static List<Articulo> GetArticles(bool publishedOnly)
        {
            return GetArticles(publishedOnly, 0, BizObject.MAXROWS);
        }
        public static List<Articulo> GetArticles(bool publishedOnly, int startRowIndex, int maximumRows)
        {
            if (!publishedOnly)
                return GetArticles(startRowIndex, maximumRows);

            List<Articulo> articles = null;
            string key = "Articles_Articles_" + publishedOnly.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articles = (List<Articulo>)BizObject.Cache[key];
            }
            else
            {
                List<ArticuloDetalles> recordset = SiteProvider.Articulos.GetArticuloPublicado(DateTime.Now,
                   GetPageIndex(startRowIndex, maximumRows), maximumRows);
                articles = GetArticuloListDeArticuloDetallesList(recordset);
                BaseArticulo.CacheData(key, articles);
            }
            return articles;
        }
        public static List<Articulo> GetArticles(bool publishedOnly, int id_categoria)
        {
            return GetArticles(publishedOnly, id_categoria, 0, BizObject.MAXROWS);
        }
        public static List<Articulo> GetArticles(bool publishedOnly, int id_categoria, int startRowIndex, int maximumRows)
        {
            if (!publishedOnly)
                return GetArticles(id_categoria, startRowIndex, maximumRows);

            if (id_categoria <= 0)
                return GetArticles(publishedOnly, startRowIndex, maximumRows);

            List<Articulo> articles = null;
            string key = "Articles_Articles_" + publishedOnly.ToString() + "_" + id_categoria.ToString() + "_" + startRowIndex.ToString() + "_" + maximumRows.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articles = (List<Articulo>)BizObject.Cache[key];
            }
            else
            {
                List<ArticuloDetalles> recordset = SiteProvider.Articulos.GetArticuloPublicadobyCategoria(
                   id_categoria, DateTime.Now,
                   GetPageIndex(startRowIndex, maximumRows), maximumRows);
                articles = GetArticuloListDeArticuloDetallesList(recordset);
                BaseArticulo.CacheData(key, articles);
            }
            return articles;
        }
        public static int GetArticleCount(bool publishedOnly)
        {
            if (publishedOnly)
                return GetArticleCount();

            int articleCount = 0;
            string key = "Articles_ArticleCount_" + publishedOnly.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articleCount = (int)BizObject.Cache[key];
            }
            else
            {
                articleCount = SiteProvider.Articulos.GetContarArticulosPublicados(DateTime.Now);
                BaseArticulo.CacheData(key, articleCount);
            }
            return articleCount;
        }
        //aki esta
        public static int GetArticleCount(bool publishedOnly, int id_categoria)
        {
            if (!publishedOnly)
                return GetArticleCount(id_categoria);

            if (id_categoria <= 0)
                return GetArticleCount(publishedOnly);

            int articleCount = 0;
            string key = "Articles_ArticleCount_" + publishedOnly.ToString() + "_" + id_categoria.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                articleCount = (int)BizObject.Cache[key];
            }
            else
            {
                articleCount = SiteProvider.Articulos.GetContarArticulosPublicadosbyCategoria(id_categoria, DateTime.Now);
                BaseArticulo.CacheData(key, articleCount);
            }
            return articleCount;
        }
        public static Articulo GetArticleByID(int id_articulo)
        {
            Articulo article = null;
            string key = "Articles_Article_" + id_articulo.ToString();

            if (BaseArticulo.Settings.EnableCaching && BizObject.Cache[key] != null)
            {
                article = (Articulo)BizObject.Cache[key];
            }
            else
            {
                article = GetArticleFromArticleDetails(SiteProvider.Articulos.GetArticulobyID(id_articulo));
                BaseArticulo.CacheData(key, article);
            }
            return article;
        }
        public static bool DeleteArticle(int ID)
        {
            bool ret = SiteProvider.Articulos.DeleteArticulo(ID);
            new RecordDeletedEvent("article", ID, null).Raise();
            BizObject.PurgeCacheItems("articles_article");
            return ret;
        }
        public static int InsertArticle(int id_categoria, string titu_arti, string resu_arti,
         string cont_arti, string ciud_arti, DateTime fech_publ_arti, DateTime fech_expi_arti,
         bool apro_arti, bool list_arti, bool actv_comn_arti, bool solo_miem_arti)
        {
            bool canApprove = (BizObject.CurrentUser.IsInRole("Administrador") || BizObject.CurrentUser.IsInRole("Moderador"));
            if (!canApprove)
                apro_arti = false;

            titu_arti = BizObject.ConvertNullToEmptyString(titu_arti);
            resu_arti = BizObject.ConvertNullToEmptyString(resu_arti);
            cont_arti = BizObject.ConvertNullToEmptyString(cont_arti);
            ciud_arti = BizObject.ConvertNullToEmptyString(ciud_arti);

            if (fech_publ_arti == DateTime.MinValue)
                fech_publ_arti = DateTime.Now;
            if (fech_expi_arti == DateTime.MinValue)
                fech_expi_arti = DateTime.MaxValue;

            ArticuloDetalles record = new ArticuloDetalles(0, DateTime.Now, BizObject.CurrentUserName,
               id_categoria, titu_arti, resu_arti, cont_arti, ciud_arti, fech_publ_arti, fech_expi_arti,
               apro_arti, list_arti, actv_comn_arti, solo_miem_arti, 0, 0, 0);
            int ret = SiteProvider.Articulos.InsertArticulo(record);

            BizObject.PurgeCacheItems("articles_article");
            return ret;
        }
        public static bool UpdateArticulo(int ID, int id_categoria, string titu_arti,string resu_arti, string cont_arti, 
            string ciud_arti, DateTime fech_publ_arti, DateTime fech_expi_arti, bool apro_arti, bool list_arti,
            bool actv_comn_arti, bool solo_miem_arti)
        {
            titu_arti = BizObject.ConvertNullToEmptyString(titu_arti);
            resu_arti = BizObject.ConvertNullToEmptyString(resu_arti);
            cont_arti = BizObject.ConvertNullToEmptyString(cont_arti);
            ciud_arti = BizObject.ConvertNullToEmptyString(ciud_arti);

            if (fech_publ_arti == DateTime.MinValue)
                fech_publ_arti = DateTime.Now;
            if (fech_expi_arti == DateTime.MinValue)
                fech_expi_arti = DateTime.MaxValue;

            ArticuloDetalles record = new ArticuloDetalles(ID, DateTime.Now, "", id_categoria,
               titu_arti, resu_arti, cont_arti, ciud_arti, fech_publ_arti, fech_expi_arti,
               apro_arti, list_arti, actv_comn_arti, solo_miem_arti, 0, 0, 0);
            bool ret = SiteProvider.Articulos.UpdateArticulo(record);

            BizObject.PurgeCacheItems("articles_article_" + ID.ToString());
            BizObject.PurgeCacheItems("articles_article");
            return ret;
        }
        public static bool AprobarArticulo(int id)
        {
            bool ret = SiteProvider.Articulos.AprobarArticulo(id);
            BizObject.PurgeCacheItems("articles_article_" + id.ToString());
            BizObject.PurgeCacheItems("articles_articles");
            return ret;
        }
        public static bool IncrementCantidadVisitas(int id)
        {
            return SiteProvider.Articulos.IncrementCantidadVisitas(id);
        }
        public static bool InsertVoto(int id, int rank_articulo)
        {
            return SiteProvider.Articulos.InsertVoto(id, rank_articulo);
        }
        private static Articulo GetArticleFromArticleDetails(ArticuloDetalles record)
        {
            if (record == null)
                return null;
            else
            {
                return new Articulo(record.Id_articulo, record.Fech_arti, record.Usua_arti,
                   record.Id_categoria, record.Titu_arti, record.Resu_arti, record.Cont_arti,
                   record.Ciud_arti, record.Fech_publ_arti, record.Fech_expi_arti,record.Apro_arti, record.List_arti, 
                   record.Actv_comn_arti, record.Solo_miem_arti,record.Cont_visi_arti, record.Voto_arti, record.Rank_arti);
            }
        }
        private static List<Articulo> GetArticuloListDeArticuloDetallesList(List<ArticuloDetalles> recordset)
        {
            List<Articulo> articles = new List<Articulo>();
            foreach (ArticuloDetalles record in recordset)
                articles.Add(GetArticleFromArticleDetails(record));
            return articles;
        }
    }
}